package myomi.ant.taskdefs;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Path;

import sun.tools.javap.Main;

public class Javap extends MatchingTask {
	private Class c;
	private Method m; 
	
	private Path classDirs;
	private File destDir;
	private boolean verbose = false; 

	public Javap() throws ClassNotFoundException, SecurityException, NoSuchMethodException {
		super();
		c = Class.forName("sun.tools.javap.Main");
		m = c.getDeclaredMethod("perform", new Class[]{String[].class});
		m.setAccessible(true);
	}

	public void setClassDir(Path classDir) {
		if (classDirs == null) {
			classDirs = classDir;
		} else {
			classDirs.append(classDir);
		}
	}
	
	public void setDestDir(File destDir) {
		this.destDir = destDir;
	}
	
	public void setVerbose(boolean verbose) {
		this.verbose = verbose;
	}
	
	public void execute() {
		log("start javap task");
		try {
			for (String dir: classDirs.list()) {
				File f = getProject().resolveFile(dir);
				DirectoryScanner scanner = getDirectoryScanner(f);
				String[] classes = scanner.getIncludedFiles();
				for (String classPath: classes) {
					javap(dir, classPath);					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		log("end javap task");
	}
	
	private void javap(String classDir, String classPath) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, ClassNotFoundException, IOException {
		PrintWriter writer = null;
		try {
			// mkdir
			File tmp = new File(destDir.getAbsolutePath() + File.separator + classPath);
			File dir = tmp.getParentFile();
			if (!dir.exists()) dir.mkdirs();
			// javap
			Main main = null;
			
			if (!tmp.getName().contains(".class")) return ;
			
			File file = new File(dir, tmp.getName().replaceAll(".class", ".javap"));
			writer = new PrintWriter(file);
			main = new Main(writer);
			String[] args = null;
			if (verbose) {
				args = new String[]{"-verbose", "-private", "-classpath", classDir, classPath.replaceAll(".class", "")};
			} else {
				args = new String[]{"-classpath", classDir, classPath.replaceAll(".class", "")};
			}
			m.invoke(main, new Object[]{args});
			log("execute javap: " + file.getAbsolutePath());
		} finally {
			if (writer != null) writer.close();
		}
	}
}
